package com.java1234.realm;

import com.java1234.dao.UserDao;
import com.java1234.entity.User;
import com.java1234.util.DbUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import java.sql.Connection;

/**
 * @author : 章仕烜
 * @create : 2019/12/22
 **/
public class UserRealm
    extends AuthorizingRealm {
    private UserDao userDao = new UserDao();
    private DbUtils dbUtil = new DbUtils();

    /**
     * 为当前登录的用户授予角色和权限，流程是这样的：
     *     当用户成功登录后，用户需要获得自己的权限，那么首先会通过principal(一般为username)
     *     去取得授权信息authorizationInfo(包含role和permission等权限信息)返回
     * @param principalCollection
     * @return 授权信息，存储了一系列授权信息，例如角色、权限
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String)principalCollection.getPrimaryPrincipal();
        // SimpleAuthorizationInfo - 简单授权信息，用于聚合角色、权限等授权信息
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Connection conn = null;
        try{
            conn=dbUtil.getCon();
            // 简单授权信息 - 存储角色信息
            authorizationInfo.setRoles(userDao.getRoles(conn,username));
            // 简单授权信息 - 存储权限信息
            authorizationInfo.setStringPermissions(userDao.getPermissions(conn,username));
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try {
                dbUtil.closeCon(conn);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return authorizationInfo;
    }

    /**
     * 验证当前登录的用户，流程是这样的：
     *     前端传过来一个(un,pwd)，后端首先在本方法中从token中获得un并从数据中读取身份信息(un,pwd)，
     *     封装为authenticationInfo,这个信息在本方法返回后会被拿去与传入的(un,pwd)比对
     * @param authenticationToken 这个token中封装了用户的身份信息
     * @return authenticationInfo 账号密码等对比信息，注意比对过程都是Shiro自动完成
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken)
            throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();
        Connection conn = null;
        try{
            conn=dbUtil.getCon();
            User user=userDao.getByUserName(conn, username);
            if(user!=null){
                AuthenticationInfo authcInfo=new SimpleAuthenticationInfo(user.getUserName(),user.getPassword(),"xx");
                return authcInfo;
            }else{
                return null;
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try {
                dbUtil.closeCon(conn);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }
}
